<!--
 *Author：jxx
 *Contact：283591387@qq.com
 *业务请在@/extension/wms/reloca/relocation.jsx或relocation.vue文件编写
 *新版本支持vue或【表.jsx]文件编写业务,文档见:https://v3.volcore.xyz/docs/view-grid、https://v3.volcore.xyz/docs/web
 -->
<template>
    <view-grid ref="grid"
               :columns="columns"
               :detail="detail"
               :details="details"
               :editFormFields="editFormFields"
               :editFormOptions="editFormOptions"
               :searchFormFields="searchFormFields"
               :searchFormOptions="searchFormOptions"
               :table="table"
               :extend="extend"
               :onInit="onInit"
               :onInited="onInited"
               :searchBefore="searchBefore"
               :searchAfter="searchAfter"
               :addBefore="addBefore"
               :updateBefore="updateBefore"
               :rowClick="rowClick"
               :modelOpenBefore="modelOpenBefore"
               :modelOpenAfter="modelOpenAfter">
        <!-- 自定义组件数据槽扩展，更多数据槽slot见文档 -->
        <template #gridHeader>
            <el-button type="primary" @click="showProductDialog">查看产品库存</el-button>
        </template>
    </view-grid>

    <!-- 产品库存弹窗 -->
    <el-dialog
        v-model="productDialogVisible"
        title="产品库存列表"
        width="80%"
        :close-on-click-modal="false"
    >
        <div class="product-search" style="margin-bottom: 15px;">
            <el-input
                v-model="productSearch"
                placeholder="搜索产品编号或产品名称"
                style="width: 300px; margin-right: 10px;"
                clearable
            />
            <el-button type="primary" @click="loadProductModels">刷新</el-button>
        </div>

        <el-table
            v-loading="productLoading"
            :data="filteredProducts"
            border
            stripe
            style="width: 100%"
            max-height="500"
        >
            <el-table-column type="index" label="序号" width="60" align="center" />
            <el-table-column prop="productCode" label="产品编号" width="150" show-overflow-tooltip />
            <el-table-column prop="productName" label="产品名称" width="150" show-overflow-tooltip />
            <el-table-column prop="productGui" label="产品规格" width="120" show-overflow-tooltip />
            <el-table-column prop="productdan" label="单位" width="80" align="center" />
            <el-table-column prop="productNum" label="数量" width="100" align="center" />
            <el-table-column prop="productCores" label="批次号" width="150" show-overflow-tooltip />
            <el-table-column prop="warehouseId" label="仓库" width="140" align="center" :formatter="formatWarehouse" />
            <el-table-column prop="reservoirId" label="库区" width="140" align="center" :formatter="formatReservoir" />
            <el-table-column prop="storageId" label="库位" width="140" align="center" :formatter="formatStorage" />
            <el-table-column label="操作" width="120" align="center" fixed="right">
                <template #default="{ row }">
                    <el-button type="primary" size="small" @click="openManageDialog(row)">产品管理</el-button>
                </template>
            </el-table-column>
        </el-table>

        <div style="margin-top: 15px; text-align: right;">
            <el-tag type="info">共 {{ productModels.length }} 条记录</el-tag>
        </div>

        <template #footer>
            <el-button @click="productDialogVisible = false">关闭</el-button>
        </template>
    </el-dialog>

    <!-- 产品管理（更改仓库位置）弹窗 -->
    <el-dialog
        v-model="manageDialogVisible"
        title="产品管理"
        width="600px"
        :close-on-click-modal="false"
    >
        <el-form :model="manageForm" label-width="100px" v-if="currentProduct">
            <el-form-item label="产品编号">
                <el-input v-model="currentProduct.productCode" disabled />
            </el-form-item>
            <el-form-item label="产品名称">
                <el-input v-model="currentProduct.productName" disabled />
            </el-form-item>
            <el-form-item label="原仓库ID">
                <el-input v-model="currentProduct.warehouseId" disabled />
            </el-form-item>
            <el-form-item label="原库区ID">
                <el-input v-model="currentProduct.reservoirId" disabled />
            </el-form-item>
            <el-form-item label="原库位ID">
                <el-input v-model="currentProduct.storageId" disabled />
            </el-form-item>
            <el-form-item label="新仓库" required>
                <el-select v-model="manageForm.newWarehouseId" placeholder="请选择新仓库" style="width: 100%;" @change="onWarehouseChange">
                    <el-option
                        v-for="item in warehouseList"
                        :key="item.Id"
                        :label="item.WarehouseName"
                        :value="item.Id"
                    />
                </el-select>
            </el-form-item>
            <el-form-item label="新库区" required>
                <el-select v-model="manageForm.newReservoirId" placeholder="请选择新库区" style="width: 100%;" @change="onReservoirChange">
                    <el-option
                        v-for="item in reservoirList"
                        :key="item.Id"
                        :label="item.ReservoirareaName"
                        :value="item.Id"
                    />
                </el-select>
            </el-form-item>
            <el-form-item label="新库位" required>
                <el-select v-model="manageForm.newStorageId" placeholder="请选择新库位" style="width: 100%;">
                    <el-option
                        v-for="item in storageList"
                        :key="item.Id"
                        :label="item.StoragelocationName"
                        :value="item.Id"
                    />
                </el-select>
            </el-form-item>
            <el-form-item label="原因" required>
                <el-input
                    v-model="manageForm.reason"
                    type="textarea"
                    :rows="4"
                    placeholder="请输入转移原因"
                />
            </el-form-item>
        </el-form>
        <template #footer>
            <el-button @click="manageDialogVisible = false">取消</el-button>
            <el-button type="primary" @click="confirmManage">确定</el-button>
        </template>
    </el-dialog>
</template>
<script setup lang="jsx">
    import extend from "@/extension/wms/reloca/relocation.jsx";
    import viewOptions from './relocation/options.js'
    import { ref, reactive, getCurrentInstance, watch, onMounted, computed } from "vue";
    const grid = ref(null);
    const { proxy } = getCurrentInstance()
    //http请求，proxy.http.post/get
    const { table, editFormFields, editFormOptions, searchFormFields, searchFormOptions, columns, detail, details } = reactive(viewOptions())

    let gridRef;//对应[表.jsx]文件中this.使用方式一样
    
    // 产品库存相关数据
    const productDialogVisible = ref(false);
    const productModels = ref([]);
    const productLoading = ref(false);
    const productSearch = ref('');
    
    // 产品管理相关数据
    const manageDialogVisible = ref(false);
    const currentProduct = ref(null);
    const manageForm = reactive({
        newWarehouseId: '',
        newReservoirId: '',
        newStorageId: '',
        reason: ''
    });
    
    // 下拉框数据
    const warehouseList = ref([]);  // 仓库列表
    const reservoirList = ref([]);  // 库区列表
    const storageList = ref([]);    // 库位列表
    // 名称映射
    const warehouseNameMap = ref({}); // Id -> WarehouseName
    const reservoirNameMap = ref({}); // Id -> ReservoirareaName
    const storageNameMap = ref({});   // Id -> StoragelocationName
    
    // 过滤后的产品列表
    const filteredProducts = computed(() => {
        if (!productSearch.value) {
            return productModels.value;
        }
        const searchText = productSearch.value.toLowerCase();
        return productModels.value.filter(item => 
            (item.productCode && item.productCode.toLowerCase().includes(searchText)) ||
            (item.productName && item.productName.toLowerCase().includes(searchText))
        );
    });
    //生成对象属性初始化
    const onInit = async ($vm) => {
        gridRef = $vm;
        //与jsx中的this.xx使用一样，只需将this.xx改为gridRef.xx
        //更多属性见：https://v3.volcore.xyz/docs/view-grid
        
        // 在转移单编号字段后添加生成按钮
        const transferNoOption = editFormOptions.flat().find(option => option.field === 'TransferNo');
        if (transferNoOption) {
            // 添加生成按钮的配置
            transferNoOption.append = {
                type: 'button',
                text: '生成编号',
                icon: 'el-icon-refresh',
                click: async () => {
                    await generateTransferNo();
                }
            };
            
            // 添加字段验证规则
            transferNoOption.validator = async (rule, value, callback) => {
                if (value && !(await validateTransferNo(value))) {
                    callback(new Error('转移单编号格式不正确，应为：TF + 年月日 + 4位流水号'));
                } else {
                    callback();
                }
            };
        }
    }
    //生成对象属性初始化后,操作明细表配置用到
    const onInited = async () => {
    }
    const searchBefore = async (param) => {
        //界面查询前,可以给param.wheres添加查询参数
        //返回false，则不会执行查询
        return true;
    }
    const searchAfter = async (rows, result) => {
        return true;
    }
    const addBefore = async (formData) => {
        //新建保存前formData为对象，包括明细表，可以给给表单设置值，自己输出看formData的值
        
        // 验证转移单编号
        if (formData.TransferNo) {
            const isValid = await validateTransferNo(formData.TransferNo);
            if (!isValid) {
                proxy.$message.error('转移单编号格式不正确，请重新生成或手动输入正确格式');
                return false;
            }
        } else {
            // 如果没有编号，自动生成一个
            try {
                const response = await proxy.http.get('/api/relocation/GenerateTransferNo');
                if (response && response.status) {
                    formData.TransferNo = response.data;
                    proxy.$message.success('已自动生成转移单编号：' + response.data);
                } else {
                    proxy.$message.error('转移单编号生成失败，请手动输入');
                    return false;
                }
            } catch (error) {
                proxy.$message.error('转移单编号生成失败，请手动输入');
                return false;
            }
        }
        
        return true;
    }
    const updateBefore = async (formData) => {
        //编辑保存前formData为对象，包括明细表、删除行的Id
        
        // 验证转移单编号格式
        if (formData.TransferNo) {
            const isValid = await validateTransferNo(formData.TransferNo);
            if (!isValid) {
                proxy.$message.error('转移单编号格式不正确，请重新生成或手动输入正确格式');
                return false;
            }
        }
        
        return true;
    }
    const rowClick = ({ row, column, event }) => {
        //查询界面点击行事件
        // grid.value.toggleRowSelection(row); //单击行时选中当前行;
    }
    const modelOpenBefore = async (row) => {//弹出框打开后方法
        return true;//返回false，不会打开弹出框
    }
    const modelOpenAfter = async (row) => {
        //弹出框打开后方法,设置表单默认值,按钮操作等
        
        // 如果是新建操作且转移单编号为空，则自动生成编号
        if (gridRef.currentAction === 'Add' && !editFormFields.TransferNo) {
            await generateTransferNo();
        }
    }

    /**
     * 自动生成转移单编号
     * 调用后端API生成符合编码规则的转移单编号
     * 编码规则：TF + 年月日(YYYYMMDD) + 4位流水号
     * 例如：TF202410140001
     */
    const generateTransferNo = async () => {
        try {
            // 调用后端API生成转移单编号
            const response = await proxy.http.get('/api/relocation/GenerateTransferNo');
            
            if (response && response.status) {
                // 生成成功，设置到表单字段中
                editFormFields.TransferNo = response.data;
                proxy.$message.success('转移单编号生成成功：' + response.data);
            } else {
                // 生成失败，显示错误信息
                proxy.$message.error(response?.message || '转移单编号生成失败');
                
                // 使用备用方案：手动生成简单编号
                const fallbackNo = 'TF' + new Date().toISOString().slice(0, 10).replace(/-/g, '') + 
                                  String(Math.floor(Math.random() * 9999) + 1).padStart(4, '0');
                editFormFields.TransferNo = fallbackNo;
            }
        } catch (error) {
            console.error('生成转移单编号时发生错误：', error);
            proxy.$message.error('生成转移单编号时发生错误');
            
            // 使用备用方案：手动生成简单编号
            const fallbackNo = 'TF' + new Date().toISOString().slice(0, 10).replace(/-/g, '') + 
                              String(Math.floor(Math.random() * 9999) + 1).padStart(4, '0');
            editFormFields.TransferNo = fallbackNo;
        }
    }

    /**
     * 验证转移单编号格式
     * 调用后端API验证转移单编号格式是否符合规则
     * @param {string} transferNo - 要验证的转移单编号
     * @returns {boolean} - 验证结果
     */
    const validateTransferNo = async (transferNo) => {
        try {
            if (!transferNo) return false;
            
            // 调用后端API验证转移单编号格式
            const response = await proxy.http.post('/api/relocation/ValidateTransferNo', transferNo);
            
            if (response && response.status) {
                return response.data;
            } else {
                console.warn('转移单编号格式验证失败：', response?.message);
                return false;
            }
        } catch (error) {
            console.error('验证转移单编号格式时发生错误：', error);
            return false;
        }
    }

    /**
     * 显示产品库存弹窗
     */
    const showProductDialog = async () => {
        productDialogVisible.value = true;
        // 并行加载基础映射与产品列表
        await Promise.all([loadAllBaseMaps(), loadProductModels()]);
    }

    /**
     * 加载产品库存数据
     * 从后端API获取productmodel表的所有数据
     */
    const loadProductModels = async () => {
        productLoading.value = true;
        try {
            // 调用后端API获取产品库存数据
            const response = await proxy.http.get('api/ProductModel/GetAllProductModels');
            
            console.log('API响应:', response);
            
            if (response && response.success && response.data) {
                productModels.value = response.data || [];
                console.log('产品数据:', productModels.value);
                if (productModels.value.length > 0) {
                    console.log('第一条数据:', productModels.value[0]);
                    proxy.$message.success(`成功加载 ${productModels.value.length} 条产品库存数据`);
                } else {
                    proxy.$message.warning('产品库存数据为空');
                }
            } else {
                proxy.$message.error(response?.message || '加载产品库存数据失败');
                productModels.value = [];
            }
        } catch (error) {
            console.error('加载产品库存数据时发生错误：', error);
            proxy.$message.error('加载产品库存数据时发生错误');
            productModels.value = [];
        } finally {
            productLoading.value = false;
        }
    }

    /**
     * 加载仓库/库区/库位的名称映射
     */
    const loadAllBaseMaps = async () => {
        try {
            const [w, r, s] = await Promise.all([
                proxy.http.post('api/warehousemodelling/getPageData', { page: 1, rows: 9999, sort: 'Id', order: 'asc' }),
                proxy.http.post('api/ReservoirareaModelling/getPageData', { page: 1, rows: 9999, sort: 'Id', order: 'asc' }),
                proxy.http.post('api/storagelocationmodelling/getPageData', { page: 1, rows: 9999, sort: 'Id', order: 'asc' })
            ])
            if (w && w.rows) {
                const map = {}
                w.rows.forEach(item => { map[item.Id] = item.WarehouseName })
                warehouseNameMap.value = map
            }
            if (r && r.rows) {
                const map = {}
                r.rows.forEach(item => { map[item.Id] = item.ReservoirareaName })
                reservoirNameMap.value = map
            }
            if (s && s.rows) {
                const map = {}
                s.rows.forEach(item => { map[item.Id] = item.StoragelocationName })
                storageNameMap.value = map
            }
        } catch (e) {
            console.error('加载仓库/库区/库位名称映射失败：', e)
        }
    }

    // 列格式化：将ID显示为名称
    const formatWarehouse = (row) => {
        return warehouseNameMap.value[row.warehouseId] || row.warehouseId
    }
    const formatReservoir = (row) => {
        return reservoirNameMap.value[row.reservoirId] || row.reservoirId
    }
    const formatStorage = (row) => {
        return storageNameMap.value[row.storageId] || row.storageId
    }

    /**
     * 加载仓库列表
     */
    const loadWarehouseList = async () => {
        try {
            const response = await proxy.http.post('api/warehousemodelling/getPageData', {
                page: 1, 
                rows: 9999,
                sort: 'Id',
                order: 'asc'
            });
            console.log('仓库列表响应:', response);
            if (response && response.rows) {
                warehouseList.value = response.rows;
                console.log('仓库列表:', warehouseList.value);
            }
        } catch (error) {
            console.error('加载仓库列表失败：', error);
            proxy.$message.error('加载仓库列表失败');
        }
    }

    /**
     * 加载库区列表（根据仓库ID）
     */
    const loadReservoirList = async (warehouseId) => {
        try {
            const response = await proxy.http.post('api/ReservoirareaModelling/getPageData', {
                page: 1, 
                rows: 9999,
                wheres: [{ name: 'CId', value: warehouseId, displayType: 'int' }],
                sort: 'Id',
                order: 'asc'
            });
            console.log('库区列表响应:', response);
            if (response && response.rows) {
                reservoirList.value = response.rows;
                console.log('库区列表:', reservoirList.value);
            }
        } catch (error) {
            console.error('加载库区列表失败：', error);
            proxy.$message.error('加载库区列表失败');
        }
    }

    /**
     * 加载库位列表（根据库区ID）
     */
    const loadStorageList = async (reservoirId) => {
        try {
            const response = await proxy.http.post('api/storagelocationmodelling/getPageData', {
                page: 1, 
                rows: 9999,
                wheres: [{ name: 'KId', value: reservoirId, displayType: 'int' }],
                sort: 'Id',
                order: 'asc'
            });
            console.log('库位列表响应:', response);
            if (response && response.rows) {
                storageList.value = response.rows;
                console.log('库位列表:', storageList.value);
            }
        } catch (error) {
            console.error('加载库位列表失败：', error);
            proxy.$message.error('加载库位列表失败');
        }
    }

    /**
     * 仓库改变时的处理
     */
    const onWarehouseChange = async (warehouseId) => {
        // 清空库区和库位
        manageForm.newReservoirId = '';
        manageForm.newStorageId = '';
        reservoirList.value = [];
        storageList.value = [];
        
        // 加载新的库区列表
        if (warehouseId) {
            await loadReservoirList(warehouseId);
        }
    }

    /**
     * 库区改变时的处理
     */
    const onReservoirChange = async (reservoirId) => {
        // 清空库位
        manageForm.newStorageId = '';
        storageList.value = [];
        
        // 加载新的库位列表
        if (reservoirId) {
            await loadStorageList(reservoirId);
        }
    }

    /**
     * 打开产品管理对话框
     * @param {Object} row - 当前产品行数据
     */
    const openManageDialog = async (row) => {
        currentProduct.value = row;
        // 重置表单数据
        manageForm.newWarehouseId = '';
        manageForm.newReservoirId = '';
        manageForm.newStorageId = '';
        manageForm.reason = '';
        
        // 加载仓库列表
        await loadWarehouseList();
        
        // 如果有原仓库信息，自动填充并加载对应的库区库位
        if (row.warehouseId) {
            manageForm.newWarehouseId = row.warehouseId;
            await loadReservoirList(row.warehouseId);
            
            if (row.reservoirId) {
                manageForm.newReservoirId = row.reservoirId;
                await loadStorageList(row.reservoirId);
                
                if (row.storageId) {
                    manageForm.newStorageId = row.storageId;
                }
            }
        }
        
        manageDialogVisible.value = true;
    }

    /**
     * 确认产品管理（创建转移单）
     * 根据更改的仓库位置信息创建一条转移单记录
     */
    const confirmManage = async () => {
        // 验证必填项
        if (!manageForm.newWarehouseId || !manageForm.newReservoirId || !manageForm.newStorageId) {
            proxy.$message.warning('请填写完整的新仓库、库区、库位信息');
            return;
        }
        if (!manageForm.reason) {
            proxy.$message.warning('请填写转移原因');
            return;
        }

        try {
            // 生成转移单编号：随机数 + 日期
            const now = new Date();
            const dateStr = now.getFullYear() + 
                          String(now.getMonth() + 1).padStart(2, '0') + 
                          String(now.getDate()).padStart(2, '0');
            const randomNum = String(Math.floor(Math.random() * 10000)).padStart(4, '0');
            const transferNo = `TF${dateStr}${randomNum}`;

            // 构建转移单数据
            const transferData = {
                TransferNo: transferNo,  // 转移单编号
                TransferName: currentProduct.value.productName || '产品转移',  // 转移单名称（产品名称）
                TransferType: 1,  // 转移单类型：1=移库
                DispatchfromWarehouse: currentProduct.value.warehouseId,  // 移出仓库（原仓库）
                Inbound: manageForm.newWarehouseId,  // 移入仓库（新仓库）
                RelocationDate: now.toISOString(),  // 转移日期（ISO格式：2025-01-29T03:23:48.427Z）
                Remarks: manageForm.reason,  // 备注（原因）
                TransferState: 1  // 状态：1=已移库
            };

            console.log('提交的转移单数据:', transferData);

            // 调用后端API保存转移单（框架要求使用 SaveModel 结构）
            const response = await proxy.http.post('api/relocation/add', {
                mainData: transferData,
                detailData: [],
                delKeys: []
            });
            console.log('保存响应:', response);
            
            if (response && (response.status === true || response.status === 0)) {
                proxy.$message.success('转移单创建成功');
                
                // 关闭对话框
                manageDialogVisible.value = false;
                
                // 刷新转移单列表
                if (gridRef && gridRef.search) {
                    gridRef.search();
                }
            } else {
                proxy.$message.error(response?.message || '转移单创建失败');
            }
        } catch (error) {
            console.error('创建转移单时发生错误：', error);
            proxy.$message.error('创建转移单时发生错误');
        }
    }
    //监听表单输入，做实时计算
    //watch(() => editFormFields.字段,(newValue, oldValue) => {	})
    //对外暴露数据
    defineExpose({})
</script>
<style lang="less" scoped>
</style>
